package br.com.rookgraph.utils;

import br.com.rookgraph.Graph;
import br.com.rookgraph.aproximativo.Approximative;
import br.com.rookgraph.branchreduce.BranchReduce;
import br.com.rookgraph.branchreduce.BranchReducePlus;
import br.com.rookgraph.heuristica.Alterado;
import br.com.rookgraph.heuristica.Heuristica;
import br.com.rookgraph.heuristica.Normal;
import br.com.rookgraph.heuristica.Plus;
import br.com.rookgraph.heuristica.Plus2;


/**
 * Criado para amarar Heuristica a um determinado 
 * algoritmo que roda;
 * 
 * @author Luan Pontes
 * @singe 30-04-13
 *
 */
public enum ExecuteHeuristicas {
	
	NORMAL("Normal") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return new BranchReduce(original, tree, instance()).execute();
		}

		@Override
		public Normal instance() {
			return new Normal();
		}

	},
	
	ALTERADO("Alterado") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return new BranchReduce(original, tree, instance()).execute();
		}

		@Override
		public Alterado instance() {
			return new Alterado();
		}
	},
	
	PLUS("Plus") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return new BranchReduce(original, tree, instance()).execute();
		}

		@Override
		public Plus instance() {
			return new Plus();
		}
	},
	
	PLUS2("Plus2") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return new BranchReducePlus(original, tree, instance()).execute();
		}

		@Override
		public Plus2 instance() {
			return new Plus2();
		}
	},
	
	APPROXIMATIVE("Aproximativo") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return new Approximative(original, tree).execute(); 
		}
	
		@Override
		public Heuristica instance() {
			return null;
		}
	},
	
	PLUS2PP("Plus2++") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return new BranchReducePlus(original, tree, instance()).execute();
		}

		@Override
		public Plus2 instance() {
			return new Plus2(true);
		}
	},
	
	NENHUMA("Nenhuma") {
		@Override
		public Graph execute(Graph original, Graph tree) {
			return null;
		}

		@Override
		public Heuristica instance() {
			return null;
		}

	};
	
	private String descricao;
	
	ExecuteHeuristicas(String descricao) {
		this.descricao = descricao;
	}
	
	public abstract Heuristica instance(); 
	
	public abstract Graph execute(Graph original, Graph tree);

	@Override
	public String toString() {
		return descricao;
	}
	

	public static ExecuteHeuristicas buscarValorPorNome(String nome) {
		for (ExecuteHeuristicas v : ExecuteHeuristicas.values()) {
			if (v.toString().equalsIgnoreCase(nome)) {
				return v;
			}
		}
		
		return null;
	}
}
